#include <accent/algorithms/reverse.hpp>
#include "test_base.hpp"

TEST(Reverse, emptyRange) {
  ivec v;
  auto r = all(v);
  reverse(r);
  ASSERT_TRUE(v.empty());
}

TEST(Reverse, oneElement) {
  ivec v = { 1 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 1 }), v);
}

TEST(Reverse, twoElements) {
  ivec v = { 1, 2 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 2, 1 }), v);
}

TEST(Reverse, threeElements) {
  ivec v = { 1, 2, 3 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 3, 2, 1 }), v);
}

TEST(Reverse, fourElements) {
  ivec v = { 1, 2, 3, 4 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 4, 3, 2, 1 }), v);
}

TEST(Reverse, fiveElements) {
  ivec v = { 1, 2, 3, 4, 5 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 5, 4, 3, 2, 1 }), v);
}

TEST(Reverse, sixElements) {
  ivec v = { 1, 2, 3, 4, 5, 6 };
  auto r = all(v);
  reverse(r);
  ASSERT_EQ((ivec{ 6, 5, 4, 3, 2, 1 }), v);
}


TEST(ReverseWithPosition, emptyRange) {
  ivec v;
  auto r = all(v);
  auto p = reverse_with_position(r, r.front_position());
  ASSERT_TRUE(v.empty());
  ASSERT_TRUE(!p);
}

TEST(ReverseWithPosition, oneElement) {
  ivec v = { 1 };
  auto r = all(v);
  auto p = reverse_with_position(r, r.front_position());
  ASSERT_EQ((ivec{ 1 }), v);
  ASSERT_FALSE(!p);
  ASSERT_EQ(1, *p);
}

TEST(ReverseWithPosition, twoElements) {
  ivec v = { 1, 2 };
  auto r = all(v);
  auto p = reverse_with_position(r, r.front_position());
  ASSERT_EQ((ivec{ 2, 1 }), v);
  ASSERT_FALSE(!p);
  ASSERT_EQ(1, *p);
}

TEST(ReverseWithPosition, threeElements) {
  ivec v = { 1, 2, 3 };
  auto r = all(v), s = r;
  s.pop_front();
  auto p = reverse_with_position(r, s.front_position());
  ASSERT_EQ((ivec{ 3, 2, 1 }), v);
  ASSERT_FALSE(!p);
  ASSERT_EQ(2, *p);
}

TEST(ReverseWithPosition, fourElements) {
  ivec v = { 1, 2, 3, 4 };
  auto r = all(v), s = r;
  s.pop_back();
  auto p = reverse_with_position(r, s.back_position());
  ASSERT_EQ((ivec{ 4, 3, 2, 1 }), v);
  ASSERT_FALSE(!p);
  ASSERT_EQ(3, *p);
}

TEST(ReverseWithPosition, fiveElements) {
  ivec v = { 1, 2, 3, 4, 5 };
  auto r = all(v);
  auto p = reverse_with_position(r, r.back_position());
  ASSERT_EQ((ivec{ 5, 4, 3, 2, 1 }), v);
  ASSERT_FALSE(!p);
  ASSERT_EQ(5, *p);
}
